package cn.hg.solon.youcan.web.admin.controller.system;

import static cn.hg.solon.youcan.system.entity.table.SysDeptTableDef.SYS_DEPT;

import java.util.List;

import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.MethodType;
import org.noear.solon.core.handle.ModelAndView;
import org.noear.solon.core.handle.Result;
import org.noear.solon.data.annotation.Cache;
import org.noear.solon.data.annotation.CacheRemove;
import org.noear.solon.validation.annotation.NotNull;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hg.solon.youcan.common.annotation.Log;
import cn.hg.solon.youcan.common.constant.CacheConstants;
import cn.hg.solon.youcan.common.enums.BeanStatus;
import cn.hg.solon.youcan.common.enums.BusinessType;
import cn.hg.solon.youcan.common.web.LayuiDtree;
import cn.hg.solon.youcan.common.web.LayuiTree;
import cn.hg.solon.youcan.common.web.LayuiTreeTable;
import cn.hg.solon.youcan.system.entity.SysDept;
import cn.hg.solon.youcan.system.service.SysDeptService;
import cn.hg.solon.youcan.system.service.SysRoleService;
import cn.hg.solon.youcan.web.admin.controller.BaseAdminController;
import cn.hg.solon.youcan.web.admin.controller.system.qo.DeptQueryObject;


/**
 * @author 胡高
 */
@Controller
@Mapping("/admin/system/dept")
public class DeptController extends BaseAdminController {

    private static final String SERVICE_NAME = "公司部门";

    private static final String VIEW_PATH = "/admin/system/dept/";

    @Inject
    SysDeptService deptService;

    @Inject
    SysRoleService roleService;

    /**
     * 跳转到新增页面
     */
    @Mapping(path = "add", method = MethodType.GET)
    @SaCheckLogin
    public ModelAndView add(Context ctx, Integer parentId) {
        this.log.info("跳转到新增[{}]页面", SERVICE_NAME);

        SysDept bean = new SysDept();
        bean.setParentId(ObjUtil.isNull(parentId) ? 0 : parentId);

        ModelAndView mav = new ModelAndView(VIEW_PATH + "add.html");

        mav.put("bean", bean);

        return mav;
    }

    @Mapping(path = "add", method = MethodType.POST)
    @Log(title = SERVICE_NAME, businessType = BusinessType.CREATE)
    @SaCheckPermission(value = {"system:department:add"})
    @CacheRemove(tags = CacheConstants.SYS_DEPT_TAG)
    public Result<?> add(Context ctx, @NotNull SysDept bean) {
        this.log.info("新增[{}]记录：bean={}", SERVICE_NAME, bean);

        // 新建记录到数据库
        return this.deptService.save(bean) ? Result.succeed() : Result.failure();
    }

    @Mapping(path = "delete", method = MethodType.DELETE)
    @Log(title = SERVICE_NAME, businessType = BusinessType.DELETE)
    @SaCheckPermission(value = {"system:department:del"})
    @CacheRemove(tags = CacheConstants.SYS_DEPT_TAG)
    public Result<?> delete(Context ctx, @NotNull String ids) {
        this.log.info("删除[{}]记录：ids={}", SERVICE_NAME, ids);

        return this.deptService.removeById(ids) ? Result.succeed() : Result.failure();
    }

    /**
     * 跳转到记录展示页面
     */
    @Mapping(path = "detail", method = MethodType.GET)
    @SaCheckPermission(value = {"system:department:query"})
    public ModelAndView detail(Context ctx, int id) {
        this.log.info("跳转到[{}]展示页面：id={}", SERVICE_NAME, id);

        ModelAndView mav = new ModelAndView(VIEW_PATH + "detail.html");
        mav.put("bean", this.deptService.getById(id));

        return mav;
    }

    @Mapping(path = "dtree", method = MethodType.GET)
    @SaCheckLogin
    @Cache(key = CacheConstants.SYS_DEPT_KEY + ":tree:${id}", tags = CacheConstants.SYS_DEPT_TAG , seconds = CacheConstants.CACHE_SECONDS_ONE_HOUR)
    public LayuiDtree<?> dtree(Context ctx, int id) {
        return new LayuiDtree<>(this.deptService.listByStatus(BeanStatus.ON.name()), SYS_DEPT.ID.getName(),
            SYS_DEPT.PARENT_ID.getName(), SYS_DEPT.NAME.getName(), id);
    }

    /**
     * 跳转到编辑页面
     */
    @Mapping(path = "edit", method = MethodType.GET)
    @SaCheckLogin
    public ModelAndView edit(Context ctx, int id) {
        this.log.info("跳转到编辑[{}]页面", SERVICE_NAME);

        ModelAndView mav = new ModelAndView(VIEW_PATH + "edit.html");

        mav.put("bean", this.deptService.getById(id));

        return mav;
    }

    @Mapping(path = "edit", method = MethodType.PUT)
    @Log(title = SERVICE_NAME, businessType = BusinessType.UPDATE)
    @SaCheckPermission(value = {"system:department:edit"})
    @CacheRemove(tags = CacheConstants.SYS_DEPT_TAG)
    public Result<?> edit(Context ctx, @NotNull SysDept bean) {
        this.log.info("更新[{}]记录：bean={}", SERVICE_NAME, bean);

        if (ObjUtil.isNull(bean.getParentId())) {
            bean.setParentId(0);
        }

        // 更新到数据库
        return this.deptService.update(bean) ? Result.succeed() : Result.failure();
    }

    @Mapping(path = "", method = MethodType.GET)
    @SaCheckLogin
    public ModelAndView index(Context ctx) {
        this.log.info("跳转到[{}]列表页面", SERVICE_NAME);

        ModelAndView mav = new ModelAndView(VIEW_PATH + "index.html");

        mav.putAll(ctx.paramMap());

        return mav;
    }

    /**
     * 分页查询功能
     */
    @Mapping(path = "query", method = MethodType.POST)
    @SaCheckPermission(value = {"system:department:query"})
    @Cache(key = CacheConstants.SYS_DEPT_KEY + ":query:${query}", tags = CacheConstants.SYS_DEPT_TAG , seconds = CacheConstants.CACHE_SECONDS_ONE_HOUR)
    public LayuiTreeTable<SysDept> query(Context ctx, DeptQueryObject query) {
        this.log.info("执行[{}]查询：query={}", SERVICE_NAME, query);

        /*
         * 服务调用
         */
        List<SysDept> list = this.deptService.listByMap(BeanUtil.beanToMap(query));

        /*
         * 返回值处理
         */
        return new LayuiTreeTable<>(list, CollUtil.size(list), Integer.valueOf(0));
    }

    @Mapping(path = "queryByRole", method = MethodType.GET)
    @SaCheckLogin
    @Cache(key = CacheConstants.SYS_DEPT_KEY + ":role:${roleId}", tags = CacheConstants.SYS_DEPT_TAG , seconds = CacheConstants.CACHE_SECONDS_ONE_HOUR)
    public List<SysDept> queryByRole(Context ctx, @NotNull Integer roleId){
        this.log.info("执行[{}]查询：roleId={}", SERVICE_NAME, roleId);

        return this.deptService.listByRole(this.roleService.getById(roleId));
    }

    @Mapping(path = "tree", method = MethodType.GET)
    @SaCheckLogin
    @Cache(key = CacheConstants.SYS_DEPT_KEY + ":tree", tags = CacheConstants.SYS_DEPT_TAG , seconds = CacheConstants.CACHE_SECONDS_ONE_HOUR)
    public LayuiTree<SysDept> tree(Context ctx) {
        return new LayuiTree<>(this.deptService.listByStatus(BeanStatus.ON.name()), SYS_DEPT.ID.getName(),
            SYS_DEPT.PARENT_ID.getName(), SYS_DEPT.NAME.getName(), "checked", Integer.valueOf(0), 3);
    }
}
